package com.cmonbaby.adapter.recycleview.wrapper;

import androidx.annotation.NonNull;
import androidx.collection.SparseArrayCompat;
import androidx.recyclerview.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;

import com.cmonbaby.adapter.recycleview.RViewHolder;
import com.cmonbaby.adapter.recycleview.utils.WrapperUtils;

/**
 * RecycleView头部，底部包装类
 * @author simon 2016-9-19 下午16:05:29
 * @since JDK1.8 SDK6.0.1
 * @version V2.3.4
 */
public class HeaderAndFooterWrapper extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private static final int BASE_ITEM_TYPE_HEADER = 100000;
    private static final int BASE_ITEM_TYPE_FOOTER = 200000;

    private SparseArrayCompat<View> mHeaderViews = new SparseArrayCompat<>();
    private SparseArrayCompat<View> mFootViews = new SparseArrayCompat<>();

    private RecyclerView.Adapter mInnerAdapter;

    /**
     * 构造方法，传入RecyclerView.Adapter
     *
     * @param adapter RecyclerView.Adapter
     */
    public HeaderAndFooterWrapper(RecyclerView.Adapter adapter) {
        mInnerAdapter = adapter;
    }

    /** 为Item创建视图 */
    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        // 获得RecycleViewViewHolder对象，其中使用构造方法实现
        if (mHeaderViews.get(viewType) != null) {
            return RViewHolder.createViewHolder(parent.getContext(), mHeaderViews.get(viewType));

        } else if (mFootViews.get(viewType) != null) {
            return RViewHolder.createViewHolder(parent.getContext(), mFootViews.get(viewType));
        }
        // 如果没有头部底部，则正常显示
        return mInnerAdapter.onCreateViewHolder(parent, viewType);
    }

    /** 根据数据源的position返回需要显示的的layout的type，type的值必须从0开始 */
    @Override
    public int getItemViewType(int position) {
        if (isHeaderViewPos(position)) { // 如果有头部
            return mHeaderViews.keyAt(position);
        } else if (isFooterViewPos(position)) { // 如果有底部
            return mFootViews.keyAt(position - getHeadersCount() - getRealItemCount());
        }
        return mInnerAdapter.getItemViewType(position - getHeadersCount());
    }

    /** adapter适配器中条目数量 */
    private int getRealItemCount() {
        return mInnerAdapter.getItemCount();
    }

    /** 将数据绑定到Item的视图上 */
    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        if (isHeaderViewPos(position)) {
            return;
        }
        if (isFooterViewPos(position)) {
            return;
        }
        mInnerAdapter.onBindViewHolder(holder, position - getHeadersCount());
    }

    /** 绘制RecycleView之前，将会先调用getItemCount方法来获取Item的个数 */
    @Override
    public int getItemCount() {
        return getHeadersCount() + getFootersCount() + getRealItemCount();
    }

    @Override
    public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
        WrapperUtils.onAttachedToRecyclerView(mInnerAdapter, recyclerView, (layoutManager, oldLookup, position) -> {
            int viewType = getItemViewType(position);
            if (mHeaderViews.get(viewType) != null) {
                return layoutManager.getSpanCount();
            } else if (mFootViews.get(viewType) != null) {
                return layoutManager.getSpanCount();
            }
            if (oldLookup != null)
                return oldLookup.getSpanSize(position);
            return 1;
        });
    }

    @Override
    public void onViewAttachedToWindow(@NonNull RecyclerView.ViewHolder holder) {
        mInnerAdapter.onViewAttachedToWindow(holder);
        int position = holder.getLayoutPosition();
        if (isHeaderViewPos(position) || isFooterViewPos(position)) {
            WrapperUtils.setFullSpan(holder);
        }
    }

    /**
     * 是否有头部布局
     *
     * @param position 条目位置
     * @return true则有头部
     */
    private boolean isHeaderViewPos(int position) {
        return position < getHeadersCount(); // 如果条目位置少于头部数量
    }

    /**
     * 是否有底部布局
     *
     * @param position 条目位置
     * @return true则有底部
     */
    private boolean isFooterViewPos(int position) {
        return position >= getHeadersCount() + getRealItemCount(); // 如果条目位置大于等于头部数量+条目总数
    }

    /**
     * 增加头部布局
     *
     * @param view 头部布局View
     */
    public void addHeaderView(View view) {
        mHeaderViews.put(mHeaderViews.size() + BASE_ITEM_TYPE_HEADER, view);
    }

    /**
     * 增加底部布局
     *
     * @param view 底部布局View
     */
    public void addFootView(View view) {
        mFootViews.put(mFootViews.size() + BASE_ITEM_TYPE_FOOTER, view);
    }

    /** 获取头部布局数量 */
    private int getHeadersCount() {
        return mHeaderViews.size();
    }

    /** 获取底部布局数量 */
    private int getFootersCount() {
        return mFootViews.size();
    }

}
